freeslot(
	"S_HYPERSPARKLE",
	"SPR_HSPK",
	"SPR_MAUR",
	"MT_METSONAURA",
	"S_METSONAURA",
	"MT_HYPERSPARKLE",
	"SFX_HTRNS",
	"S_PLAY_HYPERTRNS_1",
	"S_PLAY_HYPERTRNS_2",
	"S_PLAY_HYPERTRNS_3",
	"S_PLAY_HYPERTRNS_4",
	"S_PLAY_HYPERTRNS_5",
	"S_PLAY_HYPERTRNS_6"
)

mobjinfo[MT_HYPERSPARKLE] = {
	doomednum = -1,
	spawnstate = S_HYPERSPARKLE,
	flags = MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_NOCLIPHEIGHT
}

states[S_HYPERSPARKLE] = {
	sprite = SPR_HSPK,
	frame = TR_TRANS30|A
}
addHook("PlayerThink",  function(p)
	--print(p.boosting)
	if p.hyper == nil
		local hyper = {
		isunlocked = true,
		capable = false,
		dashhelper = true,
		altdashlatch = false,
		altatomlatch = false,
		tailsflying = false,
		modernnuker = false,
		altnuker = 0,
		nasyamystichyper = false
		}
		if p.mo
			p.hyper = hyper
		else
			p.hyper = nil
		end
	end
	if p.hassupermusic == nil
		p.hassupermusic = false
	end
	--print(p.mo.color)
	--if you hypa and yo fren a bot they get spedshul effects without actually going super
	if p.bot and players[0] and players[0].valid and players[0].powers[pw_super] and players[0].hyper != nil and players[0].hyper.capable
		/*p.mo.color = players[0].mo.color
		if  p.speed > 1*FRACUNIT or p.mo.momz > 1*FRACUNIT or p.mo.momz < -1*FRACUNIT
			local AfterImageSpawn =
			P_SpawnGhostMobj(p.mo)
			AfterImageSpawn.color = p.mo.color
			AfterImageSpawn.colorized = true
		end
		local hyperparticle = P_SpawnMobjFromMobj(p.mo, P_RandomRange(-10, 10) * FRACUNIT, P_RandomRange(-10, 10) * FRACUNIT, 20*FRACUNIT, MT_SUPERSPARK) 
		hyperparticle.momx = P_RandomRange(-9, 9) * FRACUNIT
		hyperparticle.momy = P_RandomRange(-9, 9) * FRACUNIT
		hyperparticle.momz =  P_RandomRange(-9, 9) * FRACUNIT
		hyperparticle.colorized = true
		hyperparticle.color = SKINCOLOR_SUPERSILVER1
		hyperparticle.fuse = 10
		hyperparticle.scale = p.mo.scale *2/3
		hyperparticle.source = p.mo*/
		p.rings = players[0].rings
		if players[0].mo.state == S_PLAY_HYPERTRNS_1
		or players[0].mo.state == S_PLAY_HYPERTRNS_2
		or players[0].mo.state == S_PLAY_HYPERTRNS_3
		or players[0].mo.state == S_PLAY_HYPERTRNS_4
		or players[0].mo.state == S_PLAY_HYPERTRNS_5
		or players[0].mo.state == S_PLAY_HYPERTRNS_6
			if not p.powers[pw_super]
				P_DoSuperTransformation(p, false)
			end
		end
		if not p.powers[pw_super]
			p.powers[pw_super] = 1
		end
	end
	--print(p.powers[pw_super])
	--alt has his own hyper stuff so he doesn't get any of this stuff
	if p.mo.skin == "altsonic" or p.mo.skin == "vanillasonic" or (p.noxmomchar or p.xmomtoggledoff) return end
	--if you're capable of going hyper
	if (p.charflags & SF_SUPER) and p.hyper.isunlocked == true
		--You need to collect 150 rings while in your normal form before transforming to go hyper.
		if p.rings >= 150 and not p.powers[pw_super]
			p.hyper.capable = true
		end
		--If you haven't collected enough rings, fuck off, you aren't going hyper.
		if p.rings < 150 and not p.powers[pw_super]
			p.hyper.capable = false
		end
		--If you're super, and elegible for hyper bonuses...
		if (p.powers[pw_super] and p.hyper.capable == true)
			--Rock that funky music, dawg!
			if not (p.powers[pw_extralife]) and not (p.mo.skin == "modernsonic" or p.mo.skin == "msonic" or p.mo.skin == "flarethelizard" or p.mo.skin == "xtreme" or p.mo.skin == "rabbid" or p.mo.skin == "flysonic" or p.hassupermusic == true or p.autoexitmusic)
				if p.mo.skin != "metalsonic"
					if not p.rafxtra and not p.rafxtrb and not p.milnekick
						S_ChangeMusic("HYPR",true,p)
					end
				else
				--Metal gets a little something extra...
					S_ChangeMusic("SSZB",true,p)
				end
			end
			if p.mo.state == S_PLAY_SUPER_TRANS1
				p.mo.state = S_PLAY_HYPERTRNS_1
				if not (S_SoundPlaying(p.mo, sfx_htrns))
					S_StartSound(p.mo, sfx_htrns)
				end
			end
			/*if p.mo.state == S_PLAY_HYPERTRNS_5
				print("asdf")
			end*/
			if (p.mo.state == S_PLAY_HYPERTRNS_1
				or p.mo.state == S_PLAY_HYPERTRNS_2
				or p.mo.state == S_PLAY_HYPERTRNS_3
				or p.mo.state == S_PLAY_HYPERTRNS_4
				or p.mo.state == S_PLAY_HYPERTRNS_5
				or p.mo.state == S_PLAY_HYPERTRNS_6)
				p.mo.momz = 0 
				p.mo.momx = 0 
				p.mo.momy = 0
			end
			if p.mo.state == S_PLAY_HYPERTRNS_4
				or p.mo.state == S_PLAY_HYPERTRNS_5
				or p.mo.state == S_PLAY_HYPERTRNS_6
				if (p == displayplayer)
					P_StartQuake(25*FRACUNIT, 2)
				end
				if (leveltime % 2 == 0)
					P_NukeEnemies(p.mo, p.mo, 1536*FRACUNIT)
				end
			end
			if p.mo.state == S_PLAY_HYPERTRNS_4
				if p.hyperflash and p.hyperflash == 1
					if p.hyperflash and p.hyperflash == 1
						P_FlashPal(p, PAL_WHITE, 8)
					end
				end
			end
				
			--Set the correct skincolor for Hyper stuff.
			--Yet again, metal gets unique stuff. Hope he doesn't get an ego...
			if p.mo.skin != "metalsonic"
				if p.mo.state != S_PLAY_HYPERTRNS_1 and p.mo.state != S_PLAY_HYPERTRNS_2 and p.mo.state != S_PLAY_HYPERTRNS_3
					p.mo.color = (SKINCOLOR_SUPER_HYPER_1 + abs( ( (p.powers[pw_super] >> 1) % 9) - 4))
				else
					p.mo.color = p.skincolor
				end
			else
				if p.dashmode <= 3*TICRATE
					if p.mo.state != S_PLAY_HYPERTRNS_1 and p.mo.state != S_PLAY_HYPERTRNS_2 and p.mo.state != S_PLAY_HYPERTRNS_3
						p.mo.color = (SKINCOLOR_SUPER_HYPERMET_1 + abs( ( (p.powers[pw_super] >> 1) % 9) - 4))
					else
						p.mo.color = p.skincolor
					end
				end
			end
			--Adjust stats for hyper forms
			p.jumpfactor = skins[p.mo.skin].jumpfactor * 3 / 2
			if p.mo.skin != "srbii"
				p.actionspd = skins[p.mo.skin].actionspd * 2
			end
			if p.charability2 == CA2_SPINDASH
				p.mindash = 90*FRACUNIT
				p.maxdash = 170*FRACUNIT
			end
			--Hyper forms don't need to breathe.
			if (p.mo.eflags & MFE_UNDERWATER)
				p.powers[pw_underwater] = 100*TICRATE
			end
			if P_InSpaceSector(p.mo)
				p.powers[pw_spacetime] = 100*TICRATE
			end
			--Special interactions with various characters and character wads
			--Special interaction with XmasMomentum to make tails have infinite flight
			if  p.flightcounter != nil
				p.flightcounter = 1
			end
			--Special Interaction with dashmode characters. Entering dashmode causes an explosion. 
			if (p.charflags & SF_DASHMODE) and p.mo.skin != "altsonic"
				if p.dashmode > 3*TICRATE and p.hyper.dashhelper == true
					P_NukeEnemies(p.mo, p.mo, 1536*FRACUNIT)
					if p.hyperflash and p.hyperflash == 1	
						P_FlashPal(p, PAL_WHITE, 8)
					end
					if (p == displayplayer)
						P_StartQuake(50*FRACUNIT, 10)
					end
					p.hyper.dashhelper = false
				end
				if (p.dashmode <= 3*34)
					p.hyper.dashhelper = true
				end
			end
			////////////////////////////////////////////////
			--Unique hyper abilities for various characters!
			////////////////////////////////////////////////
			--Note: Some characters with hyper abilities have it inside of their code instead of here.
			--This is because some behavior of hyper characters is normally hardcoded within their wad, and needs to be directly added in there.
			--metson hover is more of a flight lol
			if p.mo.skin == "metalsonic" and p.secondjump and p.cmd.buttons&BT_JUMP
				P_SetObjectMomZ(p.mo, 8*FRACUNIT, false)
			end
			if p.mo.skin == "knuckles"
				if p.mo.state == S_PLAY_GLIDE
					if p.mo.momz*P_MobjFlip(p.mo) < 0 
						P_SetObjectMomZ(p.mo, 0*FRACUNIT, false)
						p.charflags = $ | SF_MULTIABILITY
					end
				end
			end
			--modern 'snoc doesn't have extra ring drain when flying
			if p.superboost == nil
				p.superboost = false
				p.boosting = false
			end
			if p.mo.skin == "modernsonic"
				if p.superboost == true
					if (leveltime % 5 == 0)             
					p.rings = p.rings + 1
					end
				end
				--also nukes because why the fuck not lol
				if (p.boosting == true or p.superboost == true) 
					if p.hyper.modernnuker == true
						local thok = P_SpawnMobjFromMobj(p.mo,0,0,0,MT_THOK)
						P_NukeEnemies(thok, p.mo, 600*FRACUNIT)
						P_RemoveMobj(thok)
						--P_NukeEnemies(p.mo, p.mo, 1100*FRACUNIT)
						--P_StartQuake(50*FRACUNIT, 10)
						if p.hyperflash and p.hyperflash == 1	
							P_FlashPal(p, PAL_WHITE, 8)
						end
						p.hyper.modernnuker = false
					end
				else
					p.hyper.modernnuker = true
				end
			end
			
			--eggman... rises faster? idk there's not a lot i can do with him
			if p.mo.skin == "eggman"
				if p.secondjump and p.cmd.buttons&BT_JUMP
					if p.mo.momz*P_MobjFlip(p.mo) < 90*FRACUNIT
						P_Thrust(p.mo, 90*FRACUNIT, true)
					end
				end
			end
			--altsonic instantly enters dashmode, and causes screen nukes when he uses the atom dash
			--commented out because this has been implemented into alt v6
			/*if p.mo.skin == "altsonic"
				--alt dash shit
                if p.dashmode >= 3*TICRATE
                    p.mo.colorized = true
                else
                    p.mo.colorized = false
					p.hyper.altdashlatch = true
                end
				if p.speed > p.normalspeed or p.speed == p.normalspeed then
					p.dashmode = max(p.dashmode, 3*TICRATE)
					if p.hyper.altdashlatch == true
						S_StartSound(p.mo, sfx_cdfm40)
					end
					p.hyper.altdashlatch = false
				end
				--p.hyper.altatomlatch
				--alt nuke shit
				if p.mo.puatomdash == 1
					if p.hyper.altatomlatch == true
						p.hyper.altnuker = 3
						p.hyper.altatomlatch = false
					end
				else
					p.hyper.altatomlatch = true
				end
				if p.hyper.altnuker == 2
					P_NukeEnemies(p.mo, p.mo, 1100*FRACUNIT)
					P_StartQuake(50*FRACUNIT, 10)
					P_FlashPal(p, PAL_WHITE, 8)
				end
				if p.hyper.altnuker > 0
					p.hyper.altnuker = $ - 1
				end
				--print(p.hyper.altnuker)
				p.altsonichyperhelper = false
            end*/
			--ray is gay
			--translation: ray can go upwards indefinitely and gains significantly more momentum by gliding downwards
			if p.mo.skin == "ray"
				if p.mo.state == S_PLAY_GUP1
				or p.mo.state == S_PLAY_GUP2
				or p.mo.state == S_PLAY_GUP3
				or p.mo.state == S_PLAY_GUP4
				or p.mo.state == S_PLAY_GUP5
					if p.mo.momz <= 20*FRACUNIT--*P_MobjFlip(p.mo)
						P_SetObjectMomZ(p.mo, 20*FRACUNIT, false)
					end
				end

				--print("ye")
			
				if p.mo.state == S_PLAY_GUP1
				or p.mo.state == S_PLAY_GUP2
				or p.mo.state == S_PLAY_GUP3
				or p.mo.state == S_PLAY_GUP4
				or p.mo.state == S_PLAY_GUP5
				or p.mo.state == S_PLAY_GUP1R --angling from up to flat
				or p.mo.state == S_PLAY_GUP2R
				or p.mo.state == S_PLAY_GUP3R
				or p.mo.state == S_PLAY_GUP4R --flat from up
				or p.mo.state == S_PLAY_GDWN1 --angling from flat to down
				or p.mo.state == S_PLAY_GDWN2
				or p.mo.state == S_PLAY_GDWN3
				or p.mo.state == S_PLAY_GDWN4
				or p.mo.state == S_PLAY_GDWN5
				or p.mo.state == S_PLAY_GDWN1R --angling from down to flat
				or p.mo.state == S_PLAY_GDWN2R
				or p.mo.state == S_PLAY_GDWN3R
				or p.mo.state == S_PLAY_GDWN4R
					if p.speed <= 50*FRACUNIT
						P_InstaThrust(p.mo, p.mo.angle, 50*FRACUNIT)
					end
					if p.mo.momz*P_MobjFlip(p.mo) <= 0
						if p.speed <= 70*FRACUNIT
							P_InstaThrust(p.mo, p.mo.angle, 70*FRACUNIT)
						end
					end
				end
			end
			--nasya literally just gets mystic super by draykon's request
			if p.mo.skin == "nasya"
				p.mysticsuper = true
				p.hyper.nasyamystichyper = true
			end
			--fang's bounce nukes (how original)
			if p.charability == CA_BOUNCE
				if p.mo.state == S_PLAY_BOUNCE_LANDING
					if p.hyper.bouncelatch == true
						P_NukeEnemies(p.mo, p.mo, 1100*FRACUNIT)
						if (p == displayplayer)
							P_StartQuake(50*FRACUNIT, 10)
						end
						--P_FlashPal(p, PAL_WHITE, 8)
						p.hyper.bouncelatch = false
					end
				else
					p.hyper.bouncelatch = true
				end
			end
			--some characters just get thok overwritten repeatedly lol
			if p.mo.skin == "juniosonic"	
				if p.pflags & PF_THOKKED
					p.pflags = $ & ~ PF_THOKKED
					p.usable = true
				end
			end
			--Visuals
			--afterimages
			if /*(leveltime % 2 == 0) and*/ (p.speed > 1*FRACUNIT or p.mo.momz > 1*FRACUNIT or p.mo.momz < -1*FRACUNIT)	and p.mo.skin != "metalsonic" or (p.speed >= p.runspeed or p.mo.momz > 1*FRACUNIT and p.speed >= p.runspeed or p.mo.momz < -1*FRACUNIT and p.speed >= p.runspeed) and p.mo.skin == "metalsonic"
				local AfterImageSpawn =
				P_SpawnGhostMobj(p.mo)
				if p.mo.skin != "metalsonic"
					AfterImageSpawn.color = p.mo.color
				else
					AfterImageSpawn.color = SKINCOLOR_METALSONICAURA
				end
				AfterImageSpawn.colorized = true
				AfterImageSpawn.rollangle = p.mo.rollangle
			end
			if p.mo.skin != "metalsonic"
				local hyperparticle = P_SpawnMobjFromMobj(p.mo, P_RandomRange(-10, 10) * FRACUNIT, P_RandomRange(-10, 10) * FRACUNIT, 20*FRACUNIT, MT_SUPERSPARK) 
					hyperparticle.momx = P_RandomRange(-9, 9) * FRACUNIT
					hyperparticle.momy = P_RandomRange(-9, 9) * FRACUNIT
					hyperparticle.momz =  P_RandomRange(-9, 9) * FRACUNIT
					hyperparticle.colorized = true
					hyperparticle.color = (SKINCOLOR_SUPER_HYPERMET_1 + abs( ( (p.powers[pw_super] >> 1) % 9) - 4))
					hyperparticle.fuse = 10
					hyperparticle.scale = p.mo.scale *2/3
					hyperparticle.source = p.mo
			else
				local hyperparticle = P_SpawnMobjFromMobj(p.mo, P_RandomRange(-10, 10) * FRACUNIT, P_RandomRange(-10, 10) * FRACUNIT, 20*FRACUNIT, MT_SUPERSPARK) 
				hyperparticle.momx = P_RandomRange(-9, 9) * FRACUNIT
				hyperparticle.momy = P_RandomRange(-9, 9) * FRACUNIT
				hyperparticle.momz =  P_RandomRange(-9, 9) * FRACUNIT
				hyperparticle.colorized = true
				if P_RandomRange(1, 2) == 1
					hyperparticle.color = SKINCOLOR_YELLOW
				else
					hyperparticle.color = SKINCOLOR_CYAN
				end
				hyperparticle.fuse = 10
				hyperparticle.scale = p.mo.scale *2/3
				hyperparticle.source = p.mo
				
				local metalspark = P_SpawnMobjFromMobj(p.mo, 0, 0, 20*FRACUNIT, MT_WATERZAP)
				metalspark.momx = P_RandomRange(-9, 9) * FRACUNIT
				metalspark.momy = P_RandomRange(-9, 9) * FRACUNIT
				metalspark.momz =  P_RandomRange(-9, 9) * FRACUNIT
				if (leveltime % 7 == 0) and p.speed < p.runspeed-- and P_IsObjectOnGround(p.mo)
					local metalaura = P_SpawnMobjFromMobj(p.mo, 0, 0, 0, MT_METSONAURA)
					metalaura.fuse = 8
					--metalaura.colorized = true
					metalaura.color = SKINCOLOR_METALSONICAURA
					metalaura.source = p.mo
					metalaura.scale = p.mo.scale--+p.mo.scale*3/20
				end
			end
		else
			--reset stats if you ain't hypa
			if p.dashmode <= 3*TICRATE
				p.jumpfactor = skins[p.mo.skin].jumpfactor
			end
			if p.mo.skin != "srbii"
				p.actionspd = skins[p.mo.skin].actionspd
			end
			if p.charability2 == CA2_SPINDASH
				p.mindash = skins[p.mo.skin].mindash
				p.maxdash = skins[p.mo.skin].maxdash
			end
			if p.mo.skin == "knuckles"
				p.charflags = $ & ~ SF_MULTIABILITY
			end
			if p.hyper.nasyamystichyper == true and p.mo.skin == "nasya" and p.mysticsuper
				p.mysticsuper = false
				p.hyper.nasyamystichyper = false
			end
		end
		--helper for the flying hyper sonic script
		if p.eggc1helper == nil
			p.eggc1helper = false
		end
		if p.cmd.buttons & BT_CUSTOM1 and p.eggsuperflying == false
			p.eggc1helper = true
		end
		if not (p.cmd.buttons & BT_CUSTOM1)
			p.eggc1helper = false
		end
		--dabir used so many returns that i also need this here
		if p.eggsuperflying == false
			if (S_SoundPlaying(p.mo, sfx_hypbos))
				S_StopSoundByID(p.mo, sfx_hypbos)
			end
		end
		--print(p.hyper.capable)
	end
end)

addHook("MobjThinker", function(mo)
    if not mo.source return end
    mo.lifetime = $ or 0
    --mo.x = mo.source.x + mo.lifetime * mo.momx
    --mo.y = mo.source.y + mo.lifetime * mo.momy
    --mo.z = mo.source.z + mo.lifetime * mo.momz
	P_TeleportMove(mo, mo.source.x + mo.lifetime * mo.momx, mo.source.y + mo.lifetime * mo.momy, mo.source.z + 17*FRACUNIT + mo.lifetime * mo.momz)
    mo.lifetime = $ + 1
end, MT_SUPERSPARK)
addHook("MobjThinker", function(mo)
    if not mo.source return end
    mo.lifetime = $ or 0
	mo.color = (SKINCOLOR_METALSONICAURA_1 + abs( ( (mo.source.player.powers[pw_super] >> 1) % 8) - 4))
    --mo.x = mo.source.x + mo.lifetime * mo.momx
    --mo.y = mo.source.y + mo.lifetime * mo.momy
    --mo.z = mo.source.z + mo.lifetime * mo.momz
	--if mo.source.state != S_PLAY_JUMP and mo.source.state != S_PLAY_ROLL
		P_TeleportMove(mo, mo.source.x, mo.source.y, mo.source.z)
	--end
    mo.lifetime = $ + 1
end, MT_METSONAURA)
addHook("MobjDeath", function(target, inflictor, source)
    if source
    and source.player
    and (target.flags & MF_ENEMY) then
		if source.skin == "knuckles"
			if source.player.mo.state == S_PLAY_GLIDE and source.player.hyper.capable == true and source.player.powers[pw_super]
				P_SetObjectMomZ(source.player.mo, 18*FRACUNIT, true)
				--source.player.amybruh = true
			end
		end
    end
end) 